package cn.jdy.framework.util;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class WriteExcel {

	private PropertyDescriptor[] props;

	public WriteExcel() {
	}

	/**
	 * 下载Excel
	 * @param fileName
	 * @param titles
	 * @param fieldObj: 目前支持 一维、二维数组，一个单元格，可以由多个字段取值组合
	 * @param data
	 * @return
	 */
	public HSSFWorkbook WriteExcelData(String fileName, String titles[], Object fieldObj, List data) {
		HSSFWorkbook wb = new HSSFWorkbook();
		try {
			HSSFSheet sheet = wb.createSheet(fileName);
			HSSFRow row = sheet.createRow(0);
			HSSFCellStyle titleStyle = wb.createCellStyle();
//			titleStyle.setFillForegroundColor((short) 22);
//			titleStyle = wb.createCellStyle();
//			titleStyle.setFillForegroundColor((short) 22);
//			titleStyle.setFillPattern((short) 1);
//			titleStyle.setAlignment((short) 2);
			short color = 25;
//			titleStyle.setBorderLeft(color);
//			titleStyle.setBorderBottom(color);
//			titleStyle.setBorderRight(color);
//			titleStyle.setBorderTop(color);
//			titleStyle.setBorderBottom((short) 6);
//			titleStyle.setBottomBorderColor(color);
//			titleStyle.setBorderLeft((short) 6);
//			titleStyle.setLeftBorderColor(color);
//			titleStyle.setBorderRight((short) 6);
//			titleStyle.setRightBorderColor(color);
//			titleStyle.setBorderTop((short) 6);
//			titleStyle.setTopBorderColor(color);
//			HSSFFont titleFont = wb.createFont();
//			titleFont.setBoldweight((short) 12);
//			titleFont.setFontHeightInPoints((short) 12);
//			titleFont.setFontName("宋体");
//			titleStyle.setFont(titleFont);
			HSSFCell cell = null;
			for(int i = 0; i < titles.length; i++) {
				cell = row.createCell((short) i);
				cell.setCellValue(titles[i]);
				cell.setCellStyle(titleStyle);
			}

			HSSFCellStyle dataStyle = wb.createCellStyle();
//			dataStyle.setAlignment((short) 2);
//			dataStyle.setBorderLeft(color);
//			dataStyle.setBorderBottom(color);
//			dataStyle.setBorderRight(color);
//			dataStyle.setBorderTop(color);
//			dataStyle.setBorderBottom((short) 6);
//			dataStyle.setBottomBorderColor(color);
//			dataStyle.setBorderLeft((short) 6);
//			dataStyle.setLeftBorderColor(color);
//			dataStyle.setBorderRight((short) 6);
//			dataStyle.setRightBorderColor(color);
//			dataStyle.setBorderTop((short) 6);
//			dataStyle.setTopBorderColor(color);
//			HSSFFont dataFont = wb.createFont();
//			dataFont.setFontHeightInPoints((short) 10);
//			dataFont.setFontName("宋体");
//			dataStyle.setFont(dataFont);
			int count = data != null ? data.size() : 0;
			if(fieldObj instanceof String[]) {
				String[] fieldNames = (String[]) fieldObj;
				for(int i = 0; i < count; i++) {
					Object obj = data.get(i);
					row = sheet.createRow((short) (i + 1));
					for(int k = 0; k < fieldNames.length; k++) {
						cell = row.createCell((short) k);
						cell.setCellValue(reflectObjectFieldValue(obj, fieldNames[k]));
						cell.setCellStyle(dataStyle);
					}
				}
			}else if(fieldObj instanceof String[][]) {
				String[][] fieldNames = (String[][]) fieldObj;
				for(int i = 0; i < count; i++) {
					Object obj = data.get(i);
					row = sheet.createRow((short) (i + 1));
					for(int k = 0; k < fieldNames.length; k++) {
						String value = "";
						if(fieldNames[k].length == 1) {
							value = reflectObjectFieldValue(obj, fieldNames[k][0]);
						}else {
							for(String name : fieldNames[k])
								value += reflectObjectFieldValue(obj, name);
						}
						cell = row.createCell((short) k);
						cell.setCellValue(value);
						cell.setCellStyle(dataStyle);
					}
				}
			}


		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
		return wb;
	}

	private String reflectObjectFieldValue(Object obj, String fieldName) {
//		Method m = null;
		Object value = null;
//		StringBuffer sb = new StringBuffer("get");
		try {
			if(props==null) {
				BeanInfo bi = Introspector.getBeanInfo(obj.getClass(), Object.class);
				props = bi.getPropertyDescriptors();
			}
			String[] str = null;
			if(fieldName.indexOf(".")==-1) {
				for(int i=0,len=props.length; i<len; i++) {
					if(fieldName.equals(props[i].getName())) {
						value = props[i].getReadMethod().invoke(obj, null);
						break;
					}
				}
			}else {
				str = fieldName.split("\\.");
				if(str.length == 2) {
					for(int i=0,len=props.length; i<len; i++) {
						if(str[0].equals(props[i].getName())) {
							value = props[i].getReadMethod().invoke(obj, null);
							if(value != null) {
								BeanInfo bi = Introspector.getBeanInfo(value.getClass(), Object.class);
								PropertyDescriptor[] childProps = bi.getPropertyDescriptors();
								for(int i1=0,len1=childProps.length; i<len1; i1++) {
									if(str[1].equals(childProps[i1].getName())) {
										value = childProps[i1].getReadMethod().invoke(value, null);
										break;
									}
								}
							}
							break;
						}
					}
				} else if(str.length == 3) {
					for(int i=0,len=props.length; i<len; i++) {
						if(str[0].equals(props[i].getName())) {
							value = props[i].getReadMethod().invoke(obj, null);
							if(value != null) {
								BeanInfo bi = Introspector.getBeanInfo(value.getClass(), Object.class);
								PropertyDescriptor[] childProps = bi.getPropertyDescriptors();
								for(int i1=0,len1=childProps.length; i<len1; i1++) {
									if(str[1].equals(childProps[i1].getName())) {
										switch(childProps[i1].getPropertyType().getSimpleName()) {
											case "Set":
												Field field = value.getClass().getDeclaredField(str[1]);
												value = childProps[i1].getReadMethod().invoke(value, null);
												Set set = (Set)value;
												if(set.size()>0) {
													Class<?> clazz = (Class<?>)(((ParameterizedTypeImpl)field.getGenericType()).getActualTypeArguments()[0]);
													BeanInfo bi1 = Introspector.getBeanInfo(clazz, Object.class);
													PropertyDescriptor[] childProps1 = bi1.getPropertyDescriptors();
													for(int i2=0,len2=childProps1.length; i2<len2; i2++) {
														if(str[2].equals(childProps1[i2].getName())) {
															System.out.println(childProps1[i2].getName() + "=====" + childProps1[i2].getPropertyType().getSimpleName());
															StringBuilder sbd = new StringBuilder();
															value = null;
															Iterator iter = set.iterator();
															while(iter.hasNext()) {
																sbd.append(',').append(childProps1[i2].getReadMethod().invoke(iter.next(), null));
															}
															if(sbd.length()>1) value = sbd.substring(1);
															break;
														}
													}
												}else {
													value = null;
												}
												break;
											default:
												value = childProps[i1].getReadMethod().invoke(value, null);
												break;
										}
										break;
									}
								}
							}
							break;
						}
					}

				}
			}
//			m = obj.getClass().getMethod(sb.append(fieldName.substring(0, 1).toUpperCase()).append(fieldName.substring(1)).toString(), new Class[0]);
//			value = m.invoke(obj, new Object[0]);
		} catch(Exception e) {
			e.printStackTrace();
//			return (new StringBuilder("can't find ")).append(fieldName).toString();
		}
		return value == null ? "" : value.toString();
	}
}
